﻿using log4net.Filter;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Driver;
using Net.http;
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
 

namespace HBase.mongo {
    /**
   *┌────────────────────────────────────────────────┐
   *│　描    述：MongoServer                                                    
   *│　作    者：sgj                                              
   *│　版    本：1.0                                              
   *│　创建时间：2021/6/6 9:58:16                        
   *└────────────────────────────────────────────────┘
   **/
    public class MServer :IMServer {

        public static void timeBettwen(BsonDocument bd,  String name,DateTime? bt,DateTime? et) {
            if( bt != null && et != null ) {
                DateTime dt = ( DateTime ) bt;
                BsonDocument t = new BsonDocument();
                bd["time"] = t;
                t["$gte"] = dt.Ticks;
                DateTime e = ( DateTime ) et;
                t["$lte"] = e.Ticks;
            } else if( et != null ) {
                BsonDocument t = new BsonDocument();
                bd["time"] = t;
                DateTime e = ( DateTime ) et;
                t["$lte"] = e.Ticks;
            } else if( bt != null ) {
                DateTime dt = ( DateTime ) bt;
                BsonDocument t = new BsonDocument();
                bd["time"] = t;
                t["$gte"] = dt.Ticks;
            }

        }
        public T show<T>(String _id) {
            IMongoCollection<BsonDocument> collection = ConnectionCache.getMongoCollection<T>();
            if( collection == null ) {
                return default(T);
            }

            var q = Builders<BsonDocument>.Filter.Where(m => m["_id"] == new ObjectId(_id));

            var logger = collection.Find(q).FirstOrDefault();
           ;
            return default(T);
        }

        public BsonDocument show(string name ,string _id) {
            IMongoCollection<BsonDocument> collection = ConnectionCache.getMongoCollection(name);
            if( collection == null ) {
                return null;
            }
            var q = Builders<BsonDocument>.Filter.Where(m => m["_id"] == new ObjectId(_id));

            var logger = collection.Find(q).FirstOrDefault();
            return logger;
        }
        public void save<T>(T t) where T : BaseMongoLog {
            IMongoCollection<BsonDocument> collection = ConnectionCache.getMongoCollection<T>();
            if( collection != null ) {
                BsonDocument v = JsonUtil.getGSBsonDocument(t);    
                collection.InsertOne(v);
            }


        }
        public void InsertBatch<T>(List<T> log) where T : BaseMongoLog {


            if( log.Count > 0 ) {
                Type t = log[0].GetType();
                IMongoCollection<BsonDocument> collection = ConnectionCache.getMongoCollection(t);
                if( collection == null ) {
                    return;
                }
                List<BsonDocument> res = new List<BsonDocument>();
                foreach( T t1 in log ) {
                    res.Add(JsonUtil.getGSBsonDocument(t1));
                }
         
               

                collection.InsertMany(res);
            }
        }

        public void InsertBatch(string className ,List<object> log) {
            string name = HUtil.camelCase2_(className);
            IMongoCollection<BsonDocument> collection = ConnectionCache.getMongoCollection(name);
            if( collection == null ) {
                return;
            }
            if( log.Count > 0 ) {

                List<BsonDocument> res = new List<BsonDocument>();
                foreach( object t1 in log ) {
                    res.Add(JsonUtil.getGSBsonDocument(t1));
                }
                collection.InsertMany(res);
            }
        }

        public void InsertBatch(string className ,List<BsonDocument> defList) {
            string name = HUtil.camelCase2_(className);
            IMongoCollection<BsonDocument> collection = ConnectionCache.getMongoCollection(name);
            if( collection == null ) {
                return;
            }
            if( defList.Count == 0 ) {
                return;
            }
            foreach( BsonDocument document in defList ) {
                document.Add("_id" ,HUtil.to64());
            }
            collection.InsertMany(defList);

        }

        public Page<Object> queryPage(String name, int begin,int size, FilterDefinition<BsonDocument> filter) {
            IMongoCollection<BsonDocument> collection = ConnectionCache.getMongoCollection(name);
            if (collection == null) {
                return null;
            }



            FindOptions<BsonDocument, BsonDocument> findOpt = new FindOptions<BsonDocument, BsonDocument>();
            findOpt.Limit = size;
            findOpt.Skip = begin;
            findOpt.Sort = Builders<BsonDocument>.Sort.Descending("_id");
            var result = collection.FindAsync(filter, findOpt).Result.ToList();

            Page<Object> page = new Page<Object>();

            List<Object> logList = new List<Object>();
            foreach (BsonDocument log in result) {
                logList.Add(JsonUtil.toOb(log));
            }
            page.content = logList;
            page.totalSize = collection.CountDocuments(filter);
            return page;
        }
        public Page<Object> queryPage(String name ,int begin ,FilterDefinition<BsonDocument> filter) {

            return queryPage(name, begin, 100, filter);
        }

        public Page<Object> queryPage(String name ,MongoPageDto param) {

            IMongoCollection<BsonDocument> collection = ConnectionCache.getMongoCollection(name);
            if( collection == null ) {
                return null;
            }
            Res res = queryPage(collection ,param);
            Page<Object> page = new Page<Object>();


            List<Object> logList = new List<Object>();
            foreach( BsonDocument log in res.result ) {
                logList.Add(JsonUtil.toOb(log));
            }
            page.content = logList;
            page.totalSize = res.totalSize;
            return page;
        }



        public Page<T> queryPage<T>(MongoPageDto dto) {
            IMongoCollection<BsonDocument> collection = ConnectionCache.getMongoCollection<T>();
            if( collection == null ) {
                return null;
            }
            Res res = queryPage(collection ,dto);
            Page<T> page = new Page<T>();
            List<T> logList = new List<T>();
            foreach( BsonDocument log in res.result ) {
                T t = BsonSerializer.Deserialize<T>(log);
                logList.Add(t);
            }
            page.content = logList;
            page.totalSize = res.totalSize;
            return page;
        }

        class Res {
            public long totalSize;
            public List<BsonDocument> result;
        }
        private Res queryPage(IMongoCollection<BsonDocument> collection ,MongoPageDto dto) {
            int begin = (dto.pageNum - 1) * dto.pageSize;
            int limit = dto.pageSize;
            FilterDefinition<BsonDocument> fitter = dto.getRestrict();
           
         
            FindOptions<BsonDocument ,BsonDocument> findOpt = new FindOptions<BsonDocument ,BsonDocument>();
            findOpt.Limit = limit;
            findOpt.Skip = begin;
            findOpt.Sort = dto.getOrder();
            Res res = new Res();
            res.result = collection.FindAsync(fitter ,findOpt).Result.ToList();
           
                res.totalSize = collection.CountDocuments(fitter);
            
            return res;
        }


        public void backUp(Object t ,bool force = false) {
            if( t == null ) {
                return;
            }
            Type type = t.GetType();
            IMongoCollection<BsonDocument> collection = ConnectionCache.getMongoCollection(type);
            if( collection == null ) {
                return;
            }

         
            if( !force ) {
                long id = ( long ) HUtil.getValue(t ,"id");
               var f= Builders<BsonDocument>.Filter.Eq("id" ,id);
                if( collection.CountDocuments(f) > 0  ) {
                    return;
                }

            }
            
            var document = BsonDocument.Parse(JsonUtil.simpleSerializeObject(t));
            document.Add("_id" ,HUtil.to64());
            Dictionary<string ,DateTime> res = HUtil.getDate(t);
            foreach( var f in res ) {
                document[f.Key] = f.Value;
            }
            collection.InsertOne(document);
        }

        public void deleteCollection<T>(FilterDefinition<BsonDocument> query) {
            IMongoCollection<BsonDocument> collection = ConnectionCache.getMongoCollection<T>();
            if( collection == null ) {
                return;
            }
            collection.DeleteMany(query);
        }


        public List<BsonDocument> queryAll(string className ,FilterDefinition<BsonDocument> fitter ,SortDefinition<BsonDocument> builder) {
            string name = HUtil.camelCase2_(className);
            IMongoCollection<BsonDocument> collection = ConnectionCache.getMongoCollection(name);
            if( collection == null ) {
                return null;
            }
            FindOptions<BsonDocument ,BsonDocument> findOpt = new FindOptions<BsonDocument ,BsonDocument>();
       
            findOpt.Sort = builder;

            return collection.FindAsync<BsonDocument>(fitter ,findOpt).Result.ToList();

 
        }

    }
}
